Išmokite Tox multi-aplinkų testavimui. Aprašoma tox.ini konfigūracija, CI/CD integravimas ir pažangios strategijos Python kodo veikimui skirtingose sistemose.
Tox testavimo automatizavimas: nuodugnus kelių aplinkų testavimas pasaulinėms komandoms
Šiandieniniame pasauliniame programinės įrangos kūrimo kontekste frazė "man veikia mano kompiuteryje" yra daugiau nei tik kūrėjo klišė; tai yra didelė verslo rizika. Jūsų vartotojai, klientai ir bendradarbiai yra išsibarstę po visą pasaulį, naudodami įvairias operacines sistemas, Python versijas ir priklausomybių paketus. Kaip galite užtikrinti, kad jūsų kodas būtų ne tik funkcionalus, bet ir patikimai stabilus visiems, visur?
Atsakymas slypi sisteminiame, automatizuotame, kelių aplinkų testavime. Štai čia Tox, komandų eilutės valdomas automatizavimo įrankis, tampa nepakeičiama modernaus Python kūrėjo įrankių rinkinio dalimi. Jis standartizuoja testavimą, leisdamas apibrėžti ir vykdyti testus visoje konfigūracijų matricoje viena komanda.
Šis išsamus vadovas padės jums nuo Tox pagrindų iki pažangių kelių aplinkų testavimo strategijų. Išnagrinėsime, kaip sukurti atsparų testavimo procesą, kuris užtikrintų jūsų programinės įrangos suderinamumą, stabilumą ir pasirengimą pasaulinei auditorijai.
Kas yra kelių aplinkų testavimas ir kodėl jis yra kritiškai svarbus?
Kelių aplinkų testavimas yra jūsų testų rinkinio vykdymas naudojant kelias, skirtingas konfigūracijas. Šios konfigūracijos, arba "aplinkos", paprastai skiriasi pagal:
- Python interpretatoriaus versijas: Ar jūsų kodas veikia Python 3.8 taip pat gerai, kaip ir Python 3.11? O kaip dėl būsimo Python 3.12?
- Priklausomybių versijas: Jūsų programa gali priklausyti nuo bibliotekų, tokių kaip Django, Pandas ar Requests. Ar ji sulūš, jei vartotojas naudos šiek tiek senesnę ar naujesnę šių paketų versiją?
- Operacines sistemas: Ar jūsų kodas tinkamai tvarko failų kelius ir sistemos iškvietimus Windows, macOS ir Linux sistemose?
- Architektūras: Didėjant ARM procesorių (pvz., Apple Silicon) populiarumui, testavimas skirtingose CPU architektūrose (x86_64, arm64) tampa vis svarbesnis.
Verslo argumentai už kelių aplinkų strategiją
Laiko investavimas į tokio testavimo nustatymą nėra tik akademinis pratimas; jis turi tiesioginių verslo pasekmių:
- Sumažina palaikymo išlaidas: Ankstyvai nustatydami suderinamumo problemas, išvengsite daugybės palaikymo užklausų iš vartotojų, kurių aplinkų nebuvote numatę.
- Didina vartotojų pasitikėjimą: Programinė įranga, kuri patikimai veikia skirtinguose nustatymuose, yra suvokiama kaip aukštesnės kokybės. Tai ypač svarbu tiek atvirojo kodo bibliotekoms, tiek komerciniams produktams.
- Leidžia sklandesnius atnaujinimus: Išleidus naują Python versiją, galite ją tiesiog įtraukti į savo testavimo matricą. Jei testai praeina, žinote, kad esate pasirengę ją palaikyti. Jei jie nepraeina, turite aiškų, veiksmų reikalaujantį sąrašą, ką reikia pataisyti.
- Palaiko pasaulines komandas: Tai užtikrina, kad kūrėjas vienoje šalyje, naudojantis naujausius įrankius, gali efektyviai bendradarbiauti su komanda kitame regione, kuri gali naudoti standartizuotą, šiek tiek senesnį įmonės paketą.
Pristatome Tox: jūsų automatizavimo komandų centrą
Tox sukurtas elegantiškai išspręsti šią problemą. Iš esmės, Tox automatizuoja izoliuotų Python virtualių aplinkų kūrimą, jose įdiegia jūsų projektą ir jo priklausomybes, o tada vykdo apibrėžtas komandas (pvz., testus, linterius ar dokumentacijos kūrimą).
Visa tai valdoma vienu, paprastu konfigūracijos failu: tox.ini
.
Pradedame: diegimas ir pagrindinė konfigūracija
Diegimas yra paprastas su pip:
pip install tox
Toliau, sukurkite tox.ini
failą savo projekto šakniniame kataloge. Pradėkime nuo minimalios konfigūracijos, kad patikrintume kelias Python versijas.
Pavyzdys: Pagrindinis tox.ini
[tox] min_version = 3.7 isolated_build = true envlist = py38, py39, py310, py311 [testenv] description = Run the main test suite deps = pytest commands = pytest
Išnagrinėkime tai:
[tox]
sekcija: Tai skirta globaliems Tox nustatymams.min_version
: Nurodo minimalią Tox versiją, reikalingą šiai konfigūracijai paleisti.isolated_build
: Šiuolaikinė geriausia praktika (PEP 517), kuri užtikrina, kad jūsų paketas būtų sukurtas izoliuotoje aplinkoje prieš įdiegiant jį testavimui.envlist
: Tai yra daugelio aplinkų testavimo širdis. Tai kableliais atskirtas aplinkų, kurias norite, kad Tox tvarkytų, sąrašas. Čia apibrėžėme keturias: po vieną kiekvienai Python versijai nuo 3.8 iki 3.11.[testenv]
sekcija: Tai šablonas visoms aplinkoms, apibrėžtomsenvlist
.description
: Naudingas pranešimas, paaiškinantis, ką daro aplinka.deps
: Priklausomybių, reikalingų jūsų komandoms vykdyti, sąrašas. Čia mums tereikiapytest
.commands
: Komandos, kurias reikia vykdyti virtualioje aplinkoje. Čia mes tiesiog paleidžiamepytest
testų vykdymo įrankį.
Norėdami tai paleisti, terminale eikite į savo projekto šakninį katalogą ir tiesiog įveskite:
tox
Tox dabar atliks šiuos veiksmus kiekvienai aplinkai `envlist` (py38, py39 ir t. t.):
- Ieškos atitinkamo Python interpretatoriaus jūsų sistemoje (pvz., `python3.8`, `python3.9`).
- Sukurs naują, izoliuotą virtualią aplinką
.tox/
kataloge. - Įdiegs jūsų projektą ir priklausomybes, nurodytas `deps`.
- Įvykdys komandas, nurodytas `commands`.
Jei bet kuris veiksmas nepavyksta bet kurioje aplinkoje, Tox praneš apie klaidą ir išeis su ne nuliniu būsenos kodu, todėl jis puikiai tinka nuolatinės integracijos (CI) sistemoms.
Giluminis tyrimas: galingo tox.ini
kūrimas
Pagrindinis nustatymas yra galingas, tačiau tikroji Tox magija slypi jo lanksčiose konfigūravimo parinktyse, skirtose sudėtingoms testavimo matricoms kurti.
Generatyvinės aplinkos: kombinatorinio testavimo raktas
Įsivaizduokite, kad turite biblioteką, kuri turi palaikyti Django versijas 3.2 ir 4.2, veikiančias su Python 3.9 ir 3.10. Rankinis visų keturių derinių apibrėžimas būtų pasikartojantis:
Pasikartojantis būdas: envlist = py39-django32, py39-django42, py310-django32, py310-django42
Tox pateikia daug švaresnę, generatyvinę sintaksę, naudojant garbanotus skliaustelius {}
:
Generatyvinis būdas: envlist = {py39,py310}-django{32,42}
Ši viena eilutė išplečiama į tas pačias keturias aplinkas. Šis metodas yra labai pritaikomas. Naujos Python versijos ar Django versijos pridėjimas yra tik vieno elemento pridėjimas į atitinkamą sąrašą.
Faktoriniai-sąlyginiai nustatymai: kiekvienos aplinkos pritaikymas
Dabar, kai apibrėžėme savo matricą, kaip nurodyti Tox, kad įdiegtų teisingą Django versiją kiekvienoje aplinkoje? Tai atliekama naudojant faktorinius-sąlyginius nustatymus.
[tox] envlist = {py39,py310}-django{32,42} [testenv] deps = pytest django32: Django>=3.2,<3.3 django42: Django>=4.2,<4.3 commands = pytest
Čia eilutė `django32: Django>=3.2,<3.3` sako Tox: "Įtraukti šią priklausomybę tik tuo atveju, jei aplinkos pavadinime yra faktorius `django32`." Panašiai ir `django42` atveju. Tox yra pakankamai protingas, kad išanalizuotų aplinkos pavadinimus (pvz., `py310-django42`) ir pritaikytų teisingus nustatymus.
Tai yra nepaprastai galinga funkcija, skirta valdyti:
- Priklausomybes, kurios nėra suderinamos su senesnėmis/naujesnėmis Python versijomis.
- Testavimą pagal skirtingas pagrindinės bibliotekos versijas (Pandas, NumPy, SQLAlchemy ir t. t.).
- Sąlyginį platformai specifinių priklausomybių diegimą.
Projekto struktūravimas, peržengiantis pagrindinius testus
Tvirtas kokybės procesas apima daugiau nei tik testų vykdymą. Taip pat reikia paleisti linterius, tipų tikrintuvus ir sukurti dokumentaciją. Geriausia praktika yra apibrėžti atskiras Tox aplinkas šioms užduotims.
[tox] envlist = py{39,310}, lint, typing, docs [testenv] deps = pytest commands = pytest [testenv:lint] description = Run linters (ruff, black) basepython = python3.10 deps = ruff black commands = ruff check . black --check . [testenv:typing] description = Run static type checker (mypy) basepython = python3.10 deps = mypy # also include other dependencies with type hints django djangorestframework commands = mypy my_project/ [testenv:docs] description = Build the documentation basepython = python3.10 deps = sphinx commands = sphinx-build -b html docs/source docs/build/html
Štai kas naujo:
- Specifinės aplinkos sekcijos: Pridėjome `[testenv:lint]`, `[testenv:typing]` ir `[testenv:docs]`. Šios sekcijos apibrėžia nustatymus specialiai toms pavadintoms aplinkoms, perrašydamos numatytuosius nustatymus `[testenv]`.
basepython
: Netestavimo aplinkoms, tokioms kaip `lint` ar `docs`, dažnai nereikia jų paleisti kiekviena Python versija. `basepython` leidžia mums juos pririšti prie konkretaus interpretatoriaus, todėl jie veikia greičiau ir yra labiau determinuoti.- Švarus atskyrimas: Ši struktūra palaiko jūsų priklausomybes švarias. `lint` aplinka įdiegia tik linterius; jūsų pagrindinėms testavimo aplinkoms jų nereikia.
Dabar galite paleisti visas aplinkas su `tox`, konkretų rinkinį su `tox -e py310,lint` arba tik vieną su `tox -e docs`.
Tox integravimas su CI/CD globalaus masto automatizavimui
Vietinis Tox paleidimas yra puikus, tačiau jo tikroji galia atskleidžiama, kai jis integruojamas į nuolatinės integracijos/nuolatinio diegimo (CI/CD) procesą. Tai užtikrina, kad kiekvienas kodo pakeitimas būtų automatiškai patvirtintas pagal visą jūsų testavimo matricą.
Paslaugos, tokios kaip GitHub Actions, GitLab CI ir Jenkins, puikiai tinka tam. Jos gali vykdyti jūsų užduotis skirtingose operacinėse sistemose, leidžiančios sukurti išsamią OS suderinamumo matricą.
Pavyzdys: GitHub Actions darbo eiga
Sukurkime GitHub Actions darbo eigą, kuri lygiagrečiai paleidžia mūsų Tox aplinkas Linux, macOS ir Windows sistemose.
Sukurkite failą .github/workflows/ci.yml
:
name: CI on: [push, pull_request] jobs: test: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: ['3.8', '3.9', '3.10', '3.11'] steps: - name: Check out repository uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install Tox run: pip install tox tox-gh-actions - name: Run Tox run: tox -e py
Išanalizuokime šią darbo eigą:
strategy.matrix
: Tai yra mūsų CI matricos pagrindas. GitHub Actions sukurs atskirą užduotį kiekvienai `os` ir `python-version` kombinacijai. Šiai konfigūracijai tai yra 3 operacinės sistemos × 4 Python versijos = 12 lygiagrečių užduočių.actions/setup-python@v4
: Šis standartinis veiksmas nustato konkrečią Python versiją, reikalingą kiekvienai užduočiai.tox-gh-actions
: Tai naudingas Tox papildinys, kuris automatiškai susieja Python versiją CI aplinkoje su teisinga Tox aplinka. Pavyzdžiui, užduotyje, veikiančioje su Python 3.9, `tox -e py` automatiškai išspręs vykdymą `tox -e py39`. Tai sutaupo jums nuo sudėtingos logikos rašymo jūsų CI scenarijuje.
Dabar, kiekvieną kartą, kai kodas yra patvirtinamas, visa jūsų testavimo matrica automatiškai vykdoma visose trijose pagrindinėse operacinėse sistemose. Jūs gaunate tiesioginį atsiliepimą, ar pakeitimas sukėlė nesuderinamumą, leidžiantį kurti užtikrintai pasaulinei vartotojų bazei.
Pažangios strategijos ir geriausios praktikos
Argumentų perdavimas komandoms su {posargs}
Kartais jums reikia perduoti papildomus argumentus jūsų testų vykdymo įrankiui. Pavyzdžiui, galbūt norėsite paleisti konkretų testavimo failą: pytest tests/test_api.py
. Tox palaiko tai su {posargs}
pakeitimu.
Pakeiskite savo `tox.ini`:
[testenv] deps = pytest commands = pytest {posargs}
Dabar galite paleisti Tox taip:
tox -e py310 -- -k "test_login" -v
--
atskiria Tox skirtus argumentus nuo komandai skirtų argumentų. Viskas, kas yra po jo, bus pakeista `"{posargs}"`. Tox įvykdys: pytest -k "test_login" -v
`py310` aplinkoje.
Aplinkos kintamųjų valdymas
Jūsų programa gali elgtis skirtingai, priklausomai nuo aplinkos kintamųjų (pvz., `DJANGO_SETTINGS_MODULE`). Direktyva `setenv` leidžia jums juos valdyti jūsų Tox aplinkose.
[testenv] setenv = PYTHONPATH = . MYAPP_MODE = testing [testenv:docs] setenv = SPHINX_BUILD = 1
Patarimai, kaip pagreitinti Tox paleidimus
Didėjant jūsų matricai, Tox paleidimai gali tapti lėti. Štai keli patarimai, kaip juos pagreitinti:
- Lygiagretus režimas: Paleiskite `tox -p auto`, kad Tox paleistų jūsų aplinkas lygiagrečiai, naudodamas turimą CPU branduolių skaičių. Tai labai efektyvu moderniose mašinose.
- Atrankinis aplinkų atkūrimas: Pagal numatytuosius nustatymus Tox pakartotinai naudoja aplinkas. Jei jūsų priklausomybės `tox.ini` arba `requirements.txt` pasikeičia, turite nurodyti Tox atkurti aplinką nuo nulio. Naudokite atkūrimo vėliavėlę: `tox -r -e py310`.
- CI talpyklos naudojimas: Savo CI/CD procese išsaugokite `".tox/"` katalogą talpykloje. Tai gali žymiai pagreitinti tolesnius paleidimus, nes priklausomybių nereikės atsisiųsti ir diegti kiekvieną kartą, nebent jos pasikeičia.
Globalūs naudojimo atvejai praktikoje
Panagrinėkime, kaip tai taikoma skirtingiems projektų tipams globaliame kontekste.
1 scenarijus: atvirojo kodo duomenų analizės biblioteka
Jūs prižiūrite populiarią biblioteką, sukurtą remiantis Pandas ir NumPy. Jūsų vartotojai yra duomenų mokslininkai ir analitikai visame pasaulyje.
- Iššūkis: Turite palaikyti kelias Python, Pandas, NumPy versijas ir užtikrinti, kad ji veiktų Linux serveriuose, macOS nešiojamuosiuose kompiuteriuose ir Windows staliniuose kompiuteriuose.
- Tox sprendimas:
envlist = {py39,py310,py311}-{pandas1,pandas2}-{numpy18,numpy19}
Jūsų `tox.ini` naudotų faktorinius-sąlyginius nustatymus, kad kiekvienoje aplinkoje įdiegtų teisingas bibliotekų versijas. Jūsų GitHub Actions darbo eiga patikrintų šią matricą visose trijose pagrindinėse operacinėse sistemose. Tai užtikrina, kad vartotojas Brazilijoje, naudojantis senesnę Pandas versiją, gautų tą pačią patikimą patirtį kaip ir vartotojas Japonijoje, naudojantis naujausią paketą.
2 scenarijus: įmonės SaaS programa su kliento biblioteka
Jūsų įmonė, kurios būstinė yra Europoje, teikia SaaS produktą. Jūsų klientai yra didelės, globalios korporacijos, daugelis kurių stabilumui naudoja senesnes, ilgalaikio palaikymo (LTS) operacinių sistemų ir Python versijas.
- Iššūkis: Jūsų kūrimo komanda naudoja modernius įrankius, tačiau jūsų kliento biblioteka turi būti atgal suderinama su senesnėmis įmonės aplinkomis.
- Tox sprendimas:
envlist = py38, py39, py310, py311
Jūsų `tox.ini` užtikrina, kad visi testai praeitų su Python 3.8, kuri gali būti standartas pagrindiniam klientui Šiaurės Amerikoje. Automatiškai vykdydami tai CI, jūs užkertate kelią kūrėjams atsitiktinai įdiegti funkcijas, kurios naudoja sintaksę ar bibliotekas, prieinamas tik naujesnėse Python versijose, taip užkertant kelią brangiems diegimo gedimams.
Išvada: išleiskite su pasauliniu pasitikėjimu
Kelių aplinkų testavimas nebėra prabanga; tai yra esminė praktika kuriant aukštos kokybės, profesionalią programinę įrangą. Pasitelkdami automatizavimą su Tox, šį sudėtingą iššūkį paverčiate supaprastintu, pakartotinu procesu.
Apibrėždami palaikomas aplinkas viename tox.ini
faile ir integruodami jį su CI/CD procesu, sukuriate galingą kokybės vartus. Šie vartai užtikrina, kad jūsų programa būtų tvirta, suderinama ir paruošta įvairiai, pasaulinei auditorijai. Galite nustoti jaudintis dėl baimės keliančios problemos "man veikia mano kompiuteryje" ir pradėti teikti kodą užtikrintai, kad jis veiks kiekvieno kompiuteryje, nesvarbu, kur jie yra pasaulyje.